package G1;

public class SearchEngine {
	private ArrayList<DOC> DOClist;
	private ArrayList<String> wordlist;
	public ArrayList<String> getWordlist() {
		return wordlist;
	}

	public void setWordlist(ArrayList<String> wordlist) {
		this.wordlist = wordlist;
	}

	public ArrayList<DOC> getDOClist() {
		return DOClist;
	}

	public void setDOClist(ArrayList<DOC> dOClist) {
		DOClist = dOClist;
	}

	public HCT getHCT() {
		return HCT;
	}

	public void setHCT(HCT HCT) {
		this.HCT = HCT;
	}

	private HCT HCT = new HCT();
	private HCT HCT_text = new HCT();
	private HCT HCT_author = new HCT();
	private HCT HCT_title = new HCT();

	public SearchEngine() {
		HCT = new HCT();
		HCT_text = new HCT();
		HCT_author = new HCT();
		HCT_title = new HCT();

		DOClist = new ArrayList<>(50);
		wordlist = new ArrayList<>();
	}

	public void addDOC(DOC doc) throws EmptyNodeException {
		DOClist.add(doc);
		//System.out.println(doc.getFileName() + ":"+ doc.toString().length());
		Word_parser text = new Word_parser(doc.toString());
		ArrayList<String> tokens = text.getTokens();
		for(int i =0;i<tokens.size();i++) {
			HCT.addWord(tokens.get(i).toLowerCase(), doc);
		}

		text = new Word_parser(doc.getAuthor());
		tokens = new ArrayList<>();
		tokens = text.getTokens();
		for(int i =0;i<tokens.size();i++) {
			HCT_author.addWord(tokens.get(i).toLowerCase(), doc);
		}

		text = new Word_parser(doc.getText());
		tokens = new ArrayList<>();
		tokens = text.getTokens();
		for(int i =0;i<tokens.size();i++) {
			HCT_text.addWord(tokens.get(i).toLowerCase(), doc);
		}

		text = new Word_parser(doc.getTitle());
		tokens = new ArrayList<>();
		tokens = text.getTokens();
		for(int i =0;i<tokens.size();i++) {
			HCT_title.addWord(tokens.get(i).toLowerCase(), doc);
		}

	}
	private ArrayList<String>[] queryParser(String words){
		words = words.trim();
		String tmp[] = words.split(" ");
		if(words == null || words.equals("")){
			return null;
		}
		ArrayList<String>[] rtn= new ArrayList[2];
		rtn[0] = new ArrayList<>();
		rtn[1] = new ArrayList<>();
		this.wordlist = rtn[0];
		int cnt=0;
		for(int i =0 ;i<tmp.length;i++){
			if(tmp[i]!=null && !tmp[i].equals("") ){
				if(cnt%2 == 0){
					if(!rtn[0].contains(tmp[i]))
						rtn[0].add(tmp[i]);
				}else{
					if(tmp[i].toUpperCase().equals("AND") || tmp[i].toUpperCase().equals("OR") || tmp[i].toUpperCase().equals("XOR")){
						rtn[1].add(tmp[i].toUpperCase());
					} else {
						rtn[1].add("OR");
						if(!rtn[0].contains(tmp[i]))
							rtn[0].add(tmp[i]);

					}
				}
				cnt++;
			}
		}
		int addOR = rtn[0].size()-rtn[1].size();
		while(addOR-- != 0){
			rtn[1].add("OR");
		}
		//System.out.println(rtn[0].size());
		return rtn;
	}
	
	public Searchresult search(String word, String filter) {
		ArrayList<String>[] query = queryParser(word);
		Searchresult result = new Searchresult(null,null);
		if(query != null){
			int wordcnt = query[0].size();	
			result = search_do(query[0].get(0),filter);
			if(wordcnt>1) {
				for(int i=1;i<wordcnt;i++){
					Searchresult tmp = search_do(query[0].get(i),filter);
					if(query[1].get(i-1).equals("OR")){
						System.out.println("OR");
						try{							
							result.OR(tmp);
							result.setResultHCT(tmp.getResultHCT());
						} catch(Exception e){
							e.printStackTrace();
						} 
						//result[0].setResults(OR(result[0].getResults(),tmp[0].getResults()));
					} else if(query[1].get(i-1).equals("AND")){
						System.out.println("AND "+query[0].get(i));
						try{
							result.AND(tmp);
							result.setResultHCT(tmp.getResultHCT());
						} catch(Exception e){
							e.printStackTrace();
						}
					} else if(query[1].get(i-1).equals("XOR")){
						System.out.println("XOR "+query[0].get(i));
						try{
							result.XOR(tmp);
							result.setResultHCT(tmp.getResultHCT());
						} catch(Exception e){
							e.printStackTrace();
						}
					}
				}
			}
		}
		try {
			if(result != null)
				quickSort(result.getResults(), 0, result.getResults().size()-1);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return result;
	}

	public Searchresult search_do(String word,String filter) {
		Searchresult result;
		HCT target = HCT;
		if(filter.equals("2")) {
			target = HCT_title;
		}else if(filter.equals("3")) {
			target = HCT_author;
		}else if(filter.equals("4")) {
			target = HCT_text;
		}
		HCTNode resulttmps = null;
		try {
			resulttmps = target.search(word);
		} catch (EmptyNodeException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {			
			result = new Searchresult(resulttmps.getDOCs().toList(),resulttmps);
		} catch (Exception e) {
			result = new Searchresult(null,null);
		}
		return result;
	}

	public static void quickSort (ArrayList<DOCcnt> array, int left, int right) { 
		int i = left;
		int j= right;
		int pivot=array.get(left).getCnt(); 
		do{ 
			while (array.get(i).getCnt() > pivot ){ i ++;} 
			while (array.get(j).getCnt() < pivot ){ j --;}
			if(i <= j){ 
				array.swap(i, j);
				i++; j--; 
			} 
		}while(i<j); 
		if(left<j)quickSort(array, left, j); 
		if(right>i)quickSort(array, i, right); 
	}

}
